﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Barbar.UrlGuard.Dal.Persist {
  internal class BinaryHistoryPersistor : IHistoryPersistor {
    private RecordFile m_RecordFile;
    private IBinaryFactory<MonitoringCheck> m_CheckFactory;
    private IBinaryFactory<RecordHeader> m_HeaderFactory;
    private IBinaryFactory<IndexEntry> m_IndexFactory;

    public BinaryHistoryPersistor(IBinaryFactory<MonitoringCheck> checkFactory, IBinaryFactory<RecordHeader> headerFactory, IBinaryFactory<IndexEntry> indexFactory) {
      if (checkFactory == null)
        throw new ArgumentNullException("checkFactory");

      if (headerFactory == null)
        throw new ArgumentNullException("headerFactory");

      if (indexFactory == null)
        throw new ArgumentNullException("indexFactory");

      m_CheckFactory = checkFactory;
      m_HeaderFactory = headerFactory;
      m_IndexFactory = indexFactory;
    }

      /// <summary>
      /// Make sure history logfile exists and is active
      /// </summary>
    private void EnsureFile() {
      if (m_RecordFile == null) {
        string folder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "WebMonitor");
        if (!Directory.Exists(folder))
          Directory.CreateDirectory(folder);
        string file = Path.Combine(folder, "history.log");

        m_RecordFile = new RecordFile(file, m_HeaderFactory, m_IndexFactory);
      }
    }


    #region IHistoryPersistor Members

    public void SaveCheck(Guid monitoringEntryID, MonitoringCheck check) {
      if (check == null)
        throw new ArgumentNullException("check");

      EnsureFile();

      byte[] buffer = m_CheckFactory.GetBytes(check);
      m_RecordFile.SaveRecord(monitoringEntryID, buffer, MonitoringCheck.BINARY_SIZE);
    }

    public IEnumerable<MonitoringCheck> GetAllChecks(Guid monitoringEntryID) {
      EnsureFile();

      return m_RecordFile.GetAllRecords<MonitoringCheck>(monitoringEntryID, m_CheckFactory);
    }

    /// <summary>
    /// Clear out all of the recorded history
    /// </summary>
    public void ClearHistory()
    {
        EnsureFile();
        m_RecordFile.ClearHistory();
    }

    #endregion
  }
}
